using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using Wikey.Domain.Components;
using Wikey.Entity;
using ISessionSource=Wikey.Domain.Components.ISessionSource;
using Wikey.Utilities.Extensions;

namespace Wikey.Domain.Repository {
    public interface IUserRepository : IRepository {
        User FindByCredential(Credentials credential);
        bool EmailExists(User user);
        PagedList<User> GetUserList(Pager pager);
        int Save(User user);
        List<User> SelectAll();
        User FindByName(string username);
        List<Page> FindPages(User u );
    }

    public class UserRepository : Repository, IUserRepository {

        private readonly IEncryptor Encryptor;
        
        public UserRepository(IEncryptor encryptor, ISessionSource source)
            : base(source) {
            Encryptor = encryptor;
        }
        
        public UserRepository(IEncryptor encryptor, ISession session)
            : base(session) {
            Encryptor = encryptor;
        }


        public User FindByCredential(Credentials credential) {
            var user = (from d in Context().Users
                        where d.Credential.Username == credential.Username
                        select d).First();

            if (user != null && Encryptor.IsMatch(credential.Password, user.Credential.Password)) {
                return user;
            }
            return null;
        }

        public bool EmailExists(User user) {
            return (from d in Context().Users
                    where d.Credential.Email == user.Credential.Email
                          && d.Id != user.Id
                    select d).Any();

        }

        public PagedList<User> GetUserList(Pager pager) {
            var baseQuery = from user in Context().Users
                            orderby user.Name
                            select user;

            var dataQuery = baseQuery.Skip(pager.FirstRecord).Take(pager.RecordsPerPage);
            return new PagedList<User>(pager, dataQuery as List<User>, baseQuery.Count());
        }

        public int Save(User user) {
            user.Credential.Password = user.Credential.Password.Hash();
            base.Save(user);

            return user.Id;
        }

        public List<User> SelectAll()
        {
            var users = from user in Context().Users
            orderby user.Name
            select user;

            return users.ToList();
        }

        public User FindByName(string username)
        {
            var user = Context().Users.Where(t => t.Credential.Username.Equals(username)) ;
            if (user.Count() == 0)
                return null;

            return user.FirstOrDefault();
        }

        public List<Page> FindPages(User u)
        {
            if( u == null ) return null;

            return Context().Pages.Where(p => p.CreatedBy.Id == u.Id || p.ModifiedBy.Id == u.Id ).ToList();
        }
    }
}